import java.util.HashMap;
import java.util.Map;

public class isNumber {
    //有限状态机
    public boolean isNumber(String s) {
        Map[] states = {
                new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
                new HashMap<>() {{ put('d', 2); put('.', 4); }},                           // 1.
                new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
                new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }},              // 3.
                new HashMap<>() {{ put('d', 3); }},                                        // 4.
                new HashMap<>() {{ put('s', 6); put('d', 7); }},                           // 5.
                new HashMap<>() {{ put('d', 7); }},                                        // 6.
                new HashMap<>() {{ put('d', 7); put(' ', 8); }},                           // 7.
                new HashMap<>() {{ put(' ', 8); }}                                         // 8.
        };
        int p = 0;
        char t;
        for(char c : s.toCharArray()) {
            if (c >= '0' && c <= '9') t = 'd';
            else if (c == '+' || c == '-') t = 's';
            else if (c == 'e' || c == 'E') t = 'e';
            else if (c == '.' || c == ' ') t = c;
            else t = '?';
            if (!states[p].containsKey(t)) return false;
            p = (int)states[p].get(t);
        }
        return p == 2 || p == 3 || p == 7 || p == 8;
    }

    /**
     * 判断一个字符串是否可以表示一个有效的数字
     * 此方法通过一系列条件判断来解析字符串，检查字符串是否符合数字的规则
     * 有效的数字可以包含 'e' 或 'E' 来表示指数部分，'.' 来表示小数点，以及 '+' 和 '-' 来表示正负号
     *
     * @param s 待检查的字符串
     * @return 如果字符串可以表示一个有效的数字，则返回 true；否则返回 false
     */
    public boolean isNumber2(String s) {
        // 获取字符串长度
        int len = s.length();
        // 初始化标志变量
        boolean number = false, exp = false, point = false;
        char val;
        // 遍历字符串中的每个字符
        for ( int i = 0; i < len; i++ ) {
            val = s.charAt(i);
            // 如果字符是数字，则设置number标志为true
            if ( val >= '0' && val <= '9' ) {
                number = true;
            // 如果字符是'e'或'E'，则检查之前是否已经出现过'e'或'E'，或者还没有出现过数字
            // 如果是，返回false；否则，设置exp标志为true，并重置number标志
            } else if ( val == 'e' || val == 'E' ) {
                if ( exp || !number )
                    return false;
                exp = true;
                number = false;
            // 如果字符是'.'，则检查之前是否已经出现过小数点或'e'或'E'
            // 如果是，返回false；否则，设置point标志为true
            } else if ( val == '.' ) {
                if ( point || exp )
                    return false;
                point = true;
            // 如果字符是'+'或'-'，则检查之前是否出现过字符，且前一个字符不是'e'或'E'
            // 如果是，返回false
            } else if ( val == '+' || val == '-' ) {
                if ( i != 0 && ( s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E' ) )
                    return false;
            // 如果字符不是上述任何一种情况，则返回false
            } else {
                return false;
            }
        }
        // 返回是否是一个有效的数字
        return number;
    }

}
